// 基于 axios 封装的请求模块
import axios from 'axios'

import store from '@/store'
import router from '@/router'
// import requset from '@/utils/request'
import { updateTokenAPI } from '@/api/user'

// 新建一个新的axios实例 本质还是axios
// 好处是可以根据不同的需求，封装不同的请求 --- 灵活
const ajax = axios.create({
  baseURL: 'http://toutiao.itheima.net' // 基地址 方便统一修改地址
})

// 1 拦截器：必用！！！！！！

// 2 添加请求拦截器
ajax.interceptors.request.use(config => {
  //  对 token 做统一处理 ，如果vuex中有token
  // 则在请求投中 通过 Authorization字段 携带给 后台
  if (store.state.token) {
    // 发起请求之前, 把token携带在请求头上(表明自己身份)
    config.headers.Authorization = `Bearer ${store.state.token}`
  } else {
    config.headers.Authorization = `Bearer ${store.state.refreshToken}`
  }
  return config
}, function (error) {
  // 请求错误
  return Promise.reject(error)
})

// 3 添加响应拦截器 可以对返回的数据 或者 错误 (token过期) 做统一处理
ajax.interceptors.response.use(resp => { // http状态码以 2xx或3xx开头，执行成功的回调
  // return resp

  // resp.data直接返回给组件，目的是让组件 拿到数据后 少写一层.data
  return resp.data// 做统一处理，就可以不用resp.data.data了
}, async error => { // http状态码以 4xx或5xx开头，执行失败的回调
  // console.dir(error)
  // refresh_token过期了
  if (error.response.data.message === 'refresh_token失效') {
    // 1 清空 vuex 和 本地的 token , refreshToken
    store.commit('setToken', '')
    store.commit('refreshToken', '')
    // 2 跳转到登录页面重新登录
    // replace push 是否回退的区别
    router.replace({
      path: '/login?from=' + router.currentRoute.path
    })
  }

  // 401 token 过期 或 无效
  // 解决办法
  // 1 重新登录
  // 2 token续签 (refrsh_token)
  if (error.response.status === 401) {
    // console.dir(error)
    // 重新登录
    // 1 清空 vuex 中 token
    store.commit('setToken', '')

    // 获取 新的 token
    const resp = await updateTokenAPI()
    // console.log(resp)

    // 更新vuex新的token
    store.commit('setToken', resp.data.token)

    // 发请求，完成上次未完成的请求
    // config 中记录了上次未完成的请求参数信息， 比如： method,url,data
    // 把结果 return 到组件 await 的地方
    return ajax(error.config)
    // 2 跳转到登录页面重新登录
    // replace push 是否回退的区别
    // router.replace({
    //   path: '/login?from=' + router.currentRoute.path
    // })
  }
  return Promise.reject(error)
})

// 导出自定义函数
export default ajax

// 二次请求函数 灵活导出，方便修改
// export default ({ method, url, headers, parmas, data }) => {
//   return ajax({
//     type:method,
//     method,
//     url,
//     headers,
//     parmas,
//     data
//   })
// }
